package com.ehi.demo.jersey.status;

import junit.framework.Assert;
import org.glassfish.jersey.client.ClientConfig;
import org.glassfish.jersey.jackson.JacksonFeature;
import org.glassfish.jersey.server.ServerProperties;
import org.glassfish.jersey.test.DeploymentContext;
import org.glassfish.jersey.test.JerseyTest;
import org.glassfish.jersey.test.ServletDeploymentContext;
import org.glassfish.jersey.test.TestProperties;
import org.glassfish.jersey.test.grizzly.GrizzlyWebTestContainerFactory;
import org.glassfish.jersey.test.spi.TestContainerException;
import org.glassfish.jersey.test.spi.TestContainerFactory;
import org.junit.Ignore;
import org.junit.Test;

import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;

public class ResponseBuilderContainerIntTest extends JerseyTest {

    private static final String BUILD_NUMBER = "151";

    private static final String WRONG_BUILD_NUMBER = "152";
    private Response response;

    @Override
    protected TestContainerFactory getTestContainerFactory() throws TestContainerException {
        return new GrizzlyWebTestContainerFactory();
    }

    @Override
    protected void configureClient(ClientConfig config) {
        config.register(JacksonFeature.class);
        super.configureClient(config);
    }

    @Override
    protected DeploymentContext configureDeployment() {
        forceSet(TestProperties.CONTAINER_PORT, "" + 9998);
        enable(TestProperties.LOG_TRAFFIC);
        enable(TestProperties.DUMP_ENTITY);
        return ServletDeploymentContext.forServlet(org.glassfish.jersey.servlet.ServletContainer.class).servletPath("/api").initParam(ServerProperties.RESPONSE_SET_STATUS_OVER_SEND_ERROR, "true").initParam("javax.ws.rs.Application", "com.ehi.demo.jersey.status.TestApplication").contextPath("/rb").build();
    }

    @Test
    public void shouldReturn200StatusCode() {
        String path = "test/valid";
        response = getResponse(path);
        assertResponseStatusShouldBe(200);
    }

    private Response getResponse(String path) {
        return target(path).request().accept(MediaType.APPLICATION_JSON).header("Accept-Version", BUILD_NUMBER).get();
    }

    @Test
    public void shouldReturn200StatusCodeAndSingleValueMap() {
        response = getResponse("test/single");
        assertResponseStatusShouldBe(200);
    }

    @Test
    public void shouldReturn400StatusCodeWithBadRequestMessage() {
        response = getResponse("test/invalid");
        assertResponseStatusShouldBe(400);
    }

    @Test
    public void shouldReturn400StatusCodeWhenThrowIllegalArgumentException() {
        response = getResponse("test/invalid2");
        assertResponseStatusShouldBe(400);
    }

    @Test
    public void shouldReturnEmptyObject() {
        response = getResponse("test/notfound");
        assertResponseStatusShouldBe(200);
    }

    @Test
    public void shouldReturn500StatusCodeWithExceptionMessage() {
        response = getResponse("test/exception");
        assertResponseStatusShouldBe(500);
        String errorJson = response.readEntity(String.class);
    }

    @Test
    @Ignore
    public void shouldReturn409StatusCodeWithExceptionMessage() {
        response = target("test/exception").request().accept(MediaType.APPLICATION_JSON).header("Accept-Version", WRONG_BUILD_NUMBER).get();
        assertResponseStatusShouldBe(409);
    }

    private void assertResponseStatusShouldBe(int expectedStatus) {
        Assert.assertEquals(expectedStatus, response.getStatus());
    }

}
